import json
import sys
from multiprocessing import Process

import numpy as np

from DataProcess import filter_helper

from config import stable_condition_delta_error, min_stable_breath_frequency, stable_frequency_delta_error, \
    max_stable_breath_frequency


class Process_breath_info(Process):
    def __init__(self, websocket_queue, filter_data_dict_queue, share_dict):
        super(Process_breath_info, self).__init__()
        self.websocket_queue = websocket_queue
        self.filter_data_queue = filter_data_dict_queue
        self.total_data_dict = []
        self.total_data_pure = []
        self.total_peak_records = []
        self.total_through_records = []
        self.share_dict = share_dict

    def run(self):
        print('start calc breath info process')
        while True:
            if self.filter_data_queue.qsize() > 0:
                filter_data = self.filter_data_queue.get()
                pure_data = filter_data['data_filter']
                self.calc_p_t(filter_data, pure_data)

    def send_ws_msg(self, msg):
        self.websocket_queue.put(msg)

    def calc_p_t(self, mapped_item, pure_data):
        total_data_dict = self.total_data_dict
        total_data_pure = self.total_data_pure
        total_peak_records = self.total_peak_records
        total_through_records = self.total_through_records
        total_data_dict.append(mapped_item)
        total_data_pure.append(pure_data)
        calc_len = 500
        if len(total_data_pure) >= calc_len:
            for index, item in enumerate(total_data_pure):
                if index == 0 or index == len(total_data_pure) - 1:
                    continue
                # 用滤波后的数据：index、data_arr 去检查是否有符合要求的波峰波谷，如果有，那么修改原来的dict
                point_type = filter_helper.check_suitable_p_or_t(index, total_data_pure)
                if point_type == 'P':
                    total_peak_records.append({
                        "data": item,
                        "timestamp": total_data_dict[index]['timestamp']
                    })
                elif point_type == 'Z':
                    total_through_records.append({
                        "data": item,
                        "timestamp": total_data_dict[index]['timestamp']
                    })
            try:
                self.get_breath_info()

                self.reset_val_after_calc_p_t()
            except Exception as e:
                print('calc breath info error')
                print(e)

    def get_breath_info(self):
        total_peak_records = self.total_peak_records[-6:]
        share_dict = self.share_dict
        if len(total_peak_records) <= 2:
            return None
        total_t = 0
        max_t = 0
        min_t = sys.maxsize
        total_p = 0
        max_p = 0
        min_p = sys.maxsize
        recent_t = 0.001 * abs(total_peak_records[-1]['timestamp'] - total_peak_records[-2]['timestamp'])
        recent_frequency = int(60 / recent_t)
        for index, item in enumerate(total_peak_records):
            current_p = item['data']
            total_p = total_p + current_p
            max_p = max_p if current_p < max_p else current_p
            min_p = current_p if current_p < min_p else min_p
            if index == 0:
                continue
            current_t = 0.001 * abs(
                (total_peak_records[index]['timestamp'] - total_peak_records[index - 1]['timestamp']))
            total_t = total_t + current_t
            max_t = max_t if current_t < max_t else current_t
            min_t = current_t if current_t < min_t else min_t
        avg_t = total_t / (len(total_peak_records))
        avg_p = total_p / (len(total_peak_records))
        breath_stable = False
        p_error = np.around(abs(max_p - min_p) / avg_p, 2)
        frequency = int(60 / avg_t)
        f_max = int(60 / min_t)
        f_min = int(60 / max_t)
        frequency_error = np.around(abs(f_max - f_min) / frequency, 2)
        current_p = np.around(total_peak_records[-1]['data'])
        if (p_error <= stable_condition_delta_error
                and min_stable_breath_frequency <= frequency <= max_stable_breath_frequency and p_error <= stable_condition_delta_error
                and frequency_error <= stable_frequency_delta_error):
            breath_stable = True
        msg = json.dumps({
            "name": 'fdct_info1',
            "faultScanCycleNumber": {
                "fdctAble": breath_stable,
                "peakError": p_error,
                "breathFrequency": recent_frequency,
                "frequency_error": frequency_error,
                "current_p": current_p
            }
        })
        share_dict['q_breath_info'] = recent_frequency
        self.send_ws_msg(msg)

    def reset_val_after_calc_p_t(self):
        self.total_data_dict = []
        self.total_data_pure = []
        self.total_peak_records = self.total_peak_records[-6:]
        self.total_through_records = self.total_through_records[-6:]
